#include "widget.h"
#include "ui_widget.h"

#include <QDebug>

using namespace std;   //必须要加，否则包含X11的头文件，编译会报错

using std::string;
using std::list;
using std::cout;
using std::endl;
using std::vector;
using std::fstream;

#ifdef WIN32
#include <windows.h>
#include <iostream>

WId Pid2Wid(quint64 procID, const char *lpszClassName)
{
//    char szBuf[256];
    std::wstring szBuf;
    HWND hWnd = GetTopWindow(GetDesktopWindow());
    while (hWnd)
    {
        DWORD wndProcID = 0;
        GetWindowThreadProcessId(hWnd, &wndProcID);
        if (wndProcID == procID)
        {
            qDebug()<<"match procID";
            szBuf.resize(128);
            GetClassNameW(hWnd, &szBuf[0], szBuf.size());   //WINUSERAPI int WINAPI GetClassNameW(HWND hWnd,LPWSTR lpClassName,int nMaxCount);
            szBuf.resize(wcslen(szBuf.c_str()));
            qDebug()<<"window name:"<<QString::fromStdWString(szBuf);  // "MSCTFIME UI"   "IME"   "Qt5QWindowIcon"
            if (wcscmp(szBuf.c_str(), std::wstring(lpszClassName,lpszClassName + strlen(lpszClassName)).c_str()) == 0)
            {
                return (WId)hWnd;
            }
        }
        hWnd = GetNextWindow(hWnd, GW_HWNDNEXT);
    }
    return 0;
}

#else
#include <X11/Xlib.h>
#include <X11/Xatom.h>

class WindowsMatchingPid
{
public:
    WindowsMatchingPid(Display *display, Window wRoot, unsigned long pid)
        : _display(display)
        , _pid(pid)
    {
        // Get the PID property atom.
        _atomPID = XInternAtom(display, "_NET_WM_PID", True);
        if (_atomPID == None)
        {
            cout << "No such atom" << endl;
            return;
        }

        search(wRoot);
    }

    inline const list<Window> &result() const { return _result; }

private:
    unsigned long  _pid;
    Atom           _atomPID;
    Display       *_display;
    list<Window>   _result;

private:
    void search(Window w)
    {
        // Get the PID for the current Window.
        Atom           type;
        int            format;
        unsigned long  nItems;
        unsigned long  bytesAfter;
        unsigned char *propPID = 0;
        if (Success == XGetWindowProperty(_display,
            w,
            _atomPID,
            0,
            1,
            False,
            XA_CARDINAL,
            &type,
            &format,
            &nItems,
            &bytesAfter,
            &propPID))
        {
            if (propPID != 0)
            {
                // If the PID matches, add this window to the result set.
                if (_pid == *((unsigned long *)propPID))
                    _result.push_back(w);

                XFree(propPID);
            }
        }

        // Recurse into child windows.
        Window    wRoot;
        Window    wParent;
        Window   *wChild;
        unsigned  nChildren;
        if (0 != XQueryTree(_display, w, &wRoot, &wParent, &wChild, &nChildren))
        {
            for (unsigned i = 0; i < nChildren; i++)
                search(wChild[i]);
        }
    }
};

int Pid2Wid(int nPid)
{
    // Start with the root window.
    char *pDsp = getenv("DISPLAY");
    Display *display = XOpenDisplay(pDsp);
    if (display == NULL)
    {
        return 0;
    }

    WindowsMatchingPid match(display, XDefaultRootWindow(display), nPid);
    const list<Window> &result = match.result();
    if (result.size())
    {
        return (unsigned long)(*result.begin());
    }
    else
    {
        return 0;
    }
}

#endif

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    Qt::WindowFlags flags = windowFlags();   //获取已有flags
    setWindowFlags(flags | Qt::FramelessWindowHint);   //Qt::WindowStaysOnTopHint是窗体置顶显示
    move((QApplication::desktop()->width() - this->width())/2, (QApplication::desktop()->height() - this->height())/2);

    mProc = new QProcess(this);
    connect(qApp, &QApplication::aboutToQuit, [this]() {
            mProc->kill();
            mProc->waitForFinished();
        });
}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_load_clicked()
{
//    QProcess *pProc = new QProcess(this);
     mProc->setProcessChannelMode(QProcess::ForwardedErrorChannel);

 #ifdef WIN32
     mProc->start("D:/QtProject/EmbedInterface/Inside/IndiseProcess/Inside");  // D:/360Downloads    D:\QtProject\EmbedInterface\Inside\IndiseProcess
     mProc->waitForFinished(1000);
     WId wid = Pid2Wid(mProc->processId(), "Qt5QWindowIcon");
 #else
     mProc->start("/home/action/program/EmbedInterface/Inside");
     mProc->waitForFinished(1000);
     WId wid = Pid2Wid(mProc->processId());
 #endif

     QWindow *pWin = QWindow::fromWinId(wid);
     printf("%d\t%p\t%d\n", (int)mProc->processId(), pWin, (int)wid);
     if (pWin != NULL)
     {
         QWidget *pWid = QWidget::createWindowContainer(pWin, this);
         QVBoxLayout	*tLayout = new QVBoxLayout(ui->frame2);
         tLayout->setMargin(0);
         tLayout->setSpacing(0);
         tLayout->setContentsMargins(0,0,0,0);
         tLayout->addWidget(pWid);
         tLayout->update();
     }
}

void Widget::on_close_clicked()
{
    qDebug()<<__FILE__<<__FUNCTION__;
    close();
}
